package com.probiz.estore.inventory.service;

import java.util.List;

import com.probiz.estore.common.model.inventory.Inventory;
import com.probiz.estore.common.model.inventory.InventorySettingModel;
import com.probiz.estore.common.model.inventory.InventorySearchCriteria;
import com.probiz.estore.common.model.order.SalesOrder;
import com.probiz.estore.common.model.product.ProductSku;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.GenericManager;
import com.probiz.estore.exception.OutOfStockException;

/**
 * Manager interface for Inventory, responsible for business processing, and communicate between web and persistence layer.
 *
 */
public interface InventoryManager extends GenericManager<Inventory> {
	
	
	/**
	 * 保存现有库存，从数组中获取必要参数
	 * @param productSkuIds 单品id数组
	 * @param inventorys 库存数组
	 */
	public void saveInventorysFromArrays(String[] productSkuIds,String[] inventorys);
	
	/**
	 * 调整单品的现有库存
	 * @param sku 单品
	 * @param quantityOnHand 调整后的现有库存
	 * @param comment 调整理由
	 * @return 调整后的库存实体
	 */
	public Inventory doAdjustQuantityOnHand(ProductSku sku,Integer quantityOnHand,String comment);
	/**
	 * 订单退货 增加单品库存
	 * @param sku
	 * @param quantity
	 * @return
	 */
	public Inventory doAddStock4OrderReturn(SalesOrder salesOrder,ProductSku sku,Integer quantity);
	
	/**
	 * 调整单品的低库存警告数量
	 * @param sku 单品
	 * @param reorderMinimnm 调整后的低库存警告数量
	 * @param comment 调整理由
	 * @return 调整后的库存实体
	 */
	public Inventory doAdjustReorderMinimnm(ProductSku sku,Integer reorderMinimnm,String comment);
	
	/**
	 * 为单品请求分配库存
	 * @param salesOrder 应用订单
	 * @param productSku 请求分配库存的Sku
	 * @param quantity	请求分配的库存数量  应为正数
	 * @return 返回两个数值，第一个是本次已分配的实际库存数量(正数)，第二个是本次已分配的预订数量（已取消，暂无用，返回0）
	 * @throws OutOfStockException 没有足够的实际库存和可分配给该Sku预订数量时抛出
	 */
	public Integer[] doAllocateStock(SalesOrder salesOrder,ProductSku productSku, Integer quantity)throws OutOfStockException;
	
	/**
	 * 订单退货或编辑后重新为单品请求分配库存
	 * @param salesOrder 应用订单
	 * @param productSku 请求分配库存的Sku
	 * @param quantity	请求分配的库存数量  应为正数
	 * @return 返回两个数值，第一个是本次已分配的实际库存数量(正数)
	 * 不抛出异常
	 */
	public Integer[] doAllocateStock4OrderAction(SalesOrder salesOrder,ProductSku productSku, Integer quantity);
	
	/**
	 * 订单退货或编辑后重新为单品请求分配库存
	 * @param salesOrder 应用订单
	 * @param productSku 请求分配库存的Sku
	 * @param quantity	请求分配的库存数量  应为正数
	 * @param eventType	操作类型（1=调整库存、2=分配库存(订单)、3=取消分配库存(订单)、4=释放库存(发货)、5=分配库存(订单退货)、6=订单退货入库）
	 * @return 返回两个数值，第一个是本次已分配的实际库存数量(正数)
	 * 不抛出异常
	 */
	public Integer[] doAllocateStock4OrderAction(SalesOrder salesOrder,ProductSku productSku, Integer quantity, Short eventType);
	/**
	 * 取消单品库存分配
	 * @param salesOrder 应用订单
	 * @param productSku 取消数量的Sku
	 * @param quantity	取消数量 应为正数
	 */
	public void doCancelAllocateStock(SalesOrder salesOrder,ProductSku productSku, Integer quantity);
	
	/**
	 * 对单品发货，释放其库存（真正发发时调用）
	 * @param productSkuId
	 * @param quantity 发货数量
	 */
	public void doReleaseStock(SalesOrder salesOrder,ProductSku productSku, Integer quantity);
	
	
	/**
	 * 保存库存设置
	 * @param sku 要调整的单品
	 * @param setting 设定
	 * @return 返回现在库存
	 */
	public Inventory doSaveInventorySetting(ProductSku sku,InventorySettingModel setting);
	
	/**
	 * 搜索库存
	 * @param inventorySearchCriteria 自定义搜索条件
	 * @param searchCriteria 标准搜索条件
	 * @return 搜索结果
	 */
	public List<ProductSku> searchInventory(InventorySearchCriteria inventorySearchCriteria ,SearchCriteria searchCriteria);
	
	/**
	 * 获得低库存的单品 只能是已上架的 下架的不通知
	 * @param maxSize 最大数量
	 * @return 低库存单品
	 */
	public List<ProductSku> getLowStockProductSkuLimit(Integer maxSize);
	/**
	 * 获得缺货的单品 只能是已上架的 下架的不通知
	 * @param maxSize 最大数量
	 * @return 缺货单品
	 */
	public List<ProductSku> getLackStockProductSkuLimit(Integer maxSize);
	/**
	 * 向管理员发低库存和缺货邮件
	 */
	public void sendLowAndLackStockEmails();
	
	/**
	 * 获得低库存货品总数
	 * @return
	 */
	public Long countLowStockProductSkuTotal();
	/**
	 * 获得缺货货品总数
	 * @return
	 */
	public Long countLackStockProductSkuTotal();
	
}
